I analyzed my code tonight and even found a bug in it. I already worked with a read buffer and continued reading from the tcp if packets weren't complete. Combined packets were handled correctly, but if there would be a split packet (I never saw them yet
) the rest of the packet was written on the wrong position in the buffer. I still have to test it and hope it's fine now
I'd like to share it with you guys. I removed the error handling to make the code more readable:
// buffer
const int _BUFF_SIZE = 8096;
byte[] _anbBuff = new byte[_BUFF_SIZE];
int _nBuffUsed = 0, int _nBytesRead = 0, int _nOffset = 0; // start reading from the first position in buffer
public void Listen (IAsyncResult iaResult) {
// get tcp data
_nBytesRead = _nsNetworkStream.EndRead (iaResult);
if (_nBytesRead > 0) {
_nBuffUsed += _nBytesRead; // _nBuffUsed will contain total number of bytes in buffer
// as long as the buffer contains (more) data and the size of the data is at least equal to the size of the processed packet
while (_nBuffUsed > _nOffset && _nBuffUsed >= _nOffset + _anbBuff [_nOffset]) {
// if packetsize % 4 (valid packet size)
if (_anbBuff [_nOffset] % 4 == 0) {
// copy and handle the full packet
byte[] anbPack = new byte [_anbBuff [_nOffset]];
Array.Copy(_anbBuff, _nOffset, anbPack, 0, anbPack.Length);
_handlePacket (anbPack);
}
else {
// invalid packet found, throw exception and terminate connection
}
_nOffset += _anbBuff [_nOffset]; // put offset on next packet
}
// if all packets in buffer could be processed, reset buffer pointers
if (_nBuffUsed == _nOffset) {
_nBuffUsed = _nOffset = 0;
}
// wait for more tcp data
_nsNetworkStream.BeginRead (_anbBuff, _nBuffUsed, _BUFF_SIZE - _nBuffUsed, new AsyncCallback (Listen), _tcpClient);
}
else {
// no data received, throw exception and terminate connection
}
}